home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 1 / Gold Medal Software Volume 1 (Gold Medal) (1994).iso / graphics / tierra40.arj / TIERRA / PARSE3.C < prev    next >
C/C++ Source or Header  |  1992-09-09  |  32KB  |  934 lines

  1. /* parse3.c   9-9-92  parser functions for instruction set 3 */
  2. /* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
  3.  
  4. #if INST == 3
  5.  
  6. /* in INST == 3, the array of registers maps into the registers ax, bx, cx, dx
  7.    as follows:  c.re[0] = ax, c.re[1] = bx, c.re[2] = cx, c.re[3] = dx
  8.  
  9.     {0x00, "nop0", nop, pnop},
  10.     {0x01, "nop1", nop, pnop},
  11.     {0x02, "rollu", rollu, pnop},
  12.     {0x03, "rolld", rolld, pnop},
  13.     {0x04, "enter", enter, pnop},
  14.     {0x05, "exch", exch, pnop},
  15.     {0x06, "movdi", movdi, pmovdi},
  16.     {0x07, "movid", movid, pmovid},
  17.     {0x08, "movii", movii, pmovii},
  18.     {0x09, "push", push, ppush},
  19.     {0x0a, "pop", pop, ppop},
  20.     {0x0b, "put", put, pput},
  21.     {0x0c, "get", get, pget},
  22.     {0x0d, "inc", math, pinc},
  23.     {0x0e, "dec", math, pdec},
  24.     {0x0f, "add", math3, padd},
  25.     {0x10, "sub", math3, psub},
  26.     {0x11, "zero", movdd3, pzero},
  27.     {0x12, "shl", shl, pshl},
  28.     {0x13, "not0", not0, pnot0},
  29.     {0x14, "not", not, pnot},
  30.     {0x15, "rand", movdd3, prand},
  31.     {0x16, "ifz", ifz, pifz},
  32.     {0x17, "iffl", ifz, piffl},
  33.     {0x18, "jmp", adr, ptjmp},
  34.     {0x19, "jmpb", adr, ptjmpb},
  35.     {0x1a, "call", tcall, ptcall},
  36.     {0x1b, "adr", adr3, padr},
  37.     {0x1c, "adrb", adr3, padrb},
  38.     {0x1d, "adrf", adr3, padrf},
  39.     {0x1e, "mal", malchm, pmal},
  40.     {0x1f, "divide", divide, pdivide}
  41. */
  42.  
  43. void pnop(ce) /* do nothing */
  44. Pcells  ce;
  45. {   is.iip = is.dib = 1; }
  46.  
  47. /* void movdi(ce) is.dins->inst = is.sval + flaw(ce);
  48.  * is.dval  = address of destination instruction
  49.  * is.dins  = pointer to destination instruction
  50.  * is.sval  = value to be moved to destination instruction
  51.  * is.sval2 = original value of destination instruction
  52.  */
  53. void pmovdi(ce) /* soup [AX] = BX */
  54. Pcells  ce;
  55. {   I32s  tval;
  56.  
  57.     is.iip = is.dib = 1;
  58.     if (is.eins->exec)
  59.         return ;
  60.     tval = flaw(ce);
  61.     tval = ce->c.re[mo(tval,NUMREG)] + flaw(ce);
  62.     is.dval = ad(tval);
  63.     tval = 1 + flaw(ce);
  64.     is.sval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  65. #if PLOIDY == 1
  66.     is.dins = &soup[is.dval];
  67. #else /* PLOIDY > 1 */
  68.     is.dins = &soup[is.dval][ce->d.tr];
  69. #endif /* PLOIDY > 1 */
  70.     is.sval2 = is.dins->inst;
  71. }
  72.  
  73. /* void movid(ce) *(is.dreg) = is.sins->inst + flaw(ce);
  74.  * is.sins = pointer to source instruction
  75.  * is.sval = address of source instruction
  76.  * is.dreg = destination register, where moved value will be placed
  77.  * is.dmod = value by which to modulus destination register
  78.  * is.dran = range within which to contain destination register
  79.  */
  80. void pmovid(ce) /* AX = soup [BX] */
  81. Pcells  ce;
  82. {   I32s  tval;
  83.  
  84.     is.iip = is.dib = 1;
  85.     if (is.eins->exec)
  86.         return ;
  87.     tval = flaw(ce);
  88.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  89.     tval = 1 + flaw(ce);
  90.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  91.     is.sval = ad(tval);
  92. #if PLOIDY == 1
  93.     is.sins = &soup[is.sval];
  94. #else /* PLOIDY > 1 */
  95.     is.sins = &soup[is.sval][ce->d.tr];
  96. #endif /* PLOIDY > 1 */
  97.     is.dran = SoupSize;
  98. }
  99.  
  100. /* void movii(ce) is.dins->inst = is.sins->inst;
  101.  * is.dval  = address of destination instruction
  102.  * is.sval  = address of source instruction
  103.  * is.dins  = pointer to destination instruction
  104.  * is.sins  = pointer to source instruction
  105.  * is.dtra  = track of destination instruction
  106.  * is.sval2 = original value of destination instruction
  107.  */
  108. void pmovii(ce) /* soup [AX] = soup [BX] */
  109. Pcells  ce;
  110. {   I32s  tval;
  111.  
  112.     is.iip = is.dib = 1;
  113.     if (is.eins->exec)
  114.         return ;
  115.     tval = flaw(ce);
  116.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  117.     is.dval = ad(tval);
  118.     tval = 1 + flaw(ce);
  119.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  120.     is.sval = ad(tval);
  121. #if PLOIDY == 1
  122.     is.dins = &soup[is.dval];
  123.     is.sins = &soup[is.sval];
  124. #else /* PLOIDY > 1 */
  125.     is.dins = &soup[is.dval][ce->d.tr];
  126.     is.sins = &soup[is.sval][ce->d.tr];
  127. #endif /* PLOIDY > 1 */
  128.     is.dtra = ce->d.tr;
  129.     is.sval2 = is.dins->inst;
  130. #ifdef HSEX
  131.     if (ce->d.x_over_addr)
  132.     {   if ((!ce->d.mov_daught) && (!FindMate(ce)))
  133.             ce->d.x_over_addr = ce->d.mate_addr = 0;
  134.         else UseMate(ce);
  135.     }
  136. #endif
  137. }
  138.  
  139. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  140.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  141.  * is.sval = value to be pushed onto the stack
  142.  */
  143. void ppush(ce) /* push AX onto stack */
  144. Pcells  ce;
  145. {   I32s  tval;
  146.  
  147.     is.iip = is.dib = 1;
  148.     if (is.eins->exec)
  149.         return ;
  150.     tval = flaw(ce);
  151.     is.sval = ce->c.re[mo(tval, NUMREG)];
  152. }
  153.  
  154. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  155.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  156.  * is.dreg = destination register, where value popped off stack will go
  157.  * is.dmod = value by which to modulus destination register
  158.  * is.dran = range within which to contain destination register
  159.  */
  160. void ppop(ce) /* pop AX off of stack */
  161. Pcells  ce;
  162. {   I32s  tval;
  163.  
  164.     is.iip = is.dib = 1;
  165.     if (is.eins->exec)
  166.         return ;
  167.     tval = flaw(ce);
  168.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  169.     is.dran = SoupSize;
  170. }
  171.  
  172. /* void put(ce) write a value to the output buffer
  173.  * ce->c.pb[PUTBUFSIZ]     == pointer to next output value to be written
  174.  * ce->c.pb[PUTBUFSIZ + 1] == pointer to next output value to be read
  175.  * ce->c.pb[PUTBUFSIZ + 2] == number of unread output values
  176.  *
  177.  * is.dcel  = destination cell, in whose buffer the value will be put
  178.  * is.dreg  = destination "register" in the put buffer
  179.  * is.dval3 = destination for address returned by adr()
  180.  * is.mode3 = #ifdef ICC:  0 = broadcast to other cells' get buffer
  181.  *                         1 = write to other cell's get buffer
  182.  *            #ifndef ICC: write to own put buffer (prayer)
  183.  * is.sval  = value to be placed in the dest reg
  184.  *
  185.  * #ifndef ICC specify the values used by movdd():
  186.  * is.dreg = destination register, where moved value will be placed
  187.  * is.sval = value to be placed in the dest reg
  188.  * is.dmod = value by which to modulus destination register
  189.  * is.dran = range within which to contain destination register
  190.  *
  191.  * #ifdef ICC specify the values used by adr():
  192.  * void adr(ce) find address of a template
  193.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  194.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  195.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  196.  * is.dval  = starting address for forward search
  197.  * is.dval2 = starting address for backward search
  198.  * is.dreg  = destination register where target address will be stored
  199.  * is.dreg2 = destination register where template size will be stored
  200.  * is.dreg3 = destination register where offset of target will be stored
  201.  * is.sval  = return address if template size = 0
  202.  * is.sval2 = template size, 0 = no template
  203.  * is.sval3 = search limit, and return for distance actually searched
  204.  * is.dmod  = modulus value for is.dreg
  205.  * is.dmod2 = modulus value for is.dreg2
  206.  * is.dmod3 = modulus value for is.dreg3
  207.  * is.dran  = range to maintain for is.dreg
  208.  * is.dran2 = range to maintain for is.dreg2
  209.  * is.dran3 = range to maintain for is.dreg3
  210.  */
  211. void pput(ce) /* write AX to output port; or if put template, put to input */
  212. Pcells  ce;   /* port of creature(s) with complementary get template */
  213. {   I32s    a, s = 0, adre, tval;
  214.     Pcells  dc;
  215.     I8s     md;
  216.  
  217.     is.iip = is.dib = 1;
  218.     if (is.eins->exec)
  219.         return ;
  220. #ifdef ICC
  221.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  222.     while(1) /* find size of template, s = size */
  223.     {
  224. #if PLOIDY == 1
  225.         if(soup[ad(a + s)].inst != Nop0 &&
  226.            soup[ad(a + s)].inst != Nop1)
  227. #else /* PLOIDY > 1 */
  228.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  229.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  230. #endif /* PLOIDY > 1 */
  231.             break;
  232.         s++;
  233.     }
  234.     tval = flaw(ce);
  235.     is.sval = ce->c.re[mo(tval, NUMREG)];
  236.     if (s)
  237.     {   is.dreg  = &is.dval3;  /* dest register for address */
  238.         is.dreg2 = &BitBucket; /* dest reg for template size */
  239.         is.dreg3 = &BitBucket; /* dest reg for offset */
  240.         is.sval2 = s;
  241.         is.sval3 = Put_limit;
  242.         is.dval  = ce->mm.p + ce->mm.s;
  243.         is.dval2 = ce->mm.p - 1;
  244.         is.mode  = 0;
  245.         is.mode2 = 1;
  246.         is.mode3 = 0;
  247.         is.iip   = s + 1;
  248.     }
  249.     else
  250.     {   tval = 1 + flaw(ce);
  251.         tval = ce->c.re[mo(tval, NUMREG)];
  252.         tval = ad(tval);
  253.         if (!IsFree(tval))
  254.             WhichCell(tval, &is.dcel, &md);
  255.         else
  256.             is.dreg = &BitBucket;
  257.         is.mode3 = 1;
  258.     }
  259. #else  /* ICC */
  260.     tval = flaw(ce);
  261.     is.sval = ce->c.re[mo(tval, NUMREG)];
  262.     is.dreg = &ce->c.pb[ce->c.pb[PUTBUFSIZ]];
  263. #endif /* ICC */
  264. }
  265.  
  266. /* void get(ce) *(is.dreg) = is.sval + flaw(ce);
  267.  * ce->c.gb[GETBUFSIZ]     == pointer to next input value to be read
  268.  * ce->c.gb[GETBUFSIZ + 1] == pointer to next input value to be written
  269.  * ce->c.gb[GETBUFSIZ + 2] == number of unread input values
  270.  *
  271.  * specify the values used by movdd():
  272.  * void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  273.  * is.dreg = destination register, where moved value will be placed
  274.  * is.sval = value to be placed in the dest reg
  275.  * is.dmod = value by which to modulus destination register
  276.  * is.dran = range within which to contain destination register
  277.  */
  278. void pget(ce) /* read from input port into AX */
  279. Pcells  ce;
  280. {   I32s    a, tval;
  281.  
  282.     is.iip = is.dib = 1;
  283.     if (is.eins->exec)
  284.         return ;
  285.     tval = flaw(ce);
  286.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  287.     is.sval = ce->c.gb[ce->c.gb[GETBUFSIZ]];
  288.     is.dran = SoupSize;
  289.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  290.     while(1) /* find size of template, s = size */
  291.     {
  292. #if PLOIDY == 1
  293.         if(soup[ad(a)].inst != Nop0 &&
  294.            soup[ad(a)].inst != Nop1)
  295. #else /* PLOIDY > 1 */
  296.         if(soup[ad(a)][ce->d.tr].inst != Nop0 &&
  297.            soup[ad(a)][ce->d.tr].inst != Nop1)
  298. #endif /* PLOIDY > 1 */
  299.             break;
  300.         a++; is.iip++;
  301.     }
  302. }
  303.  
  304. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  305.  * is.dreg  = destination register, where calculation will be stored
  306.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  307.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  308.  * is.dmod  = value by which to modulus destination register
  309.  * is.dran  = range within which to contain destination register
  310.  */
  311. void pinc(ce) /* AX++ */
  312. Pcells  ce;
  313. {   I32s  tval;
  314.  
  315.     is.iip = is.dib = 1;
  316.     if (is.eins->exec)
  317.         return ;
  318.     tval = flaw(ce);
  319.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  320.     tval = flaw(ce);
  321.     is.sval = ce->c.re[mo(tval, NUMREG)];
  322.     is.sval2 = 1;
  323.     is.dran = SoupSize;
  324. }
  325.  
  326. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  327.  * is.dreg  = destination register, where calculation will be stored
  328.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  329.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  330.  * is.dmod  = value by which to modulus destination register
  331.  * is.dran  = range within which to contain destination register
  332.  */
  333. void pdec(ce) /* AX-- */
  334. Pcells  ce;
  335. {   I32s  tval;
  336.  
  337.     is.iip = is.dib = 1;
  338.     if (is.eins->exec)
  339.         return ;
  340.     tval = flaw(ce);
  341.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  342.     tval = flaw(ce);
  343.     is.sval = ce->c.re[mo(tval, NUMREG)];
  344.     is.sval2 = -1;
  345.     is.dran = SoupSize;
  346. }
  347.  
  348. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  349.  * is.dreg  = destination register, where calculation will be stored
  350.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  351.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  352.  * is.dmod  = value by which to modulus destination register
  353.  * is.dran  = range within which to contain destination register
  354.  */
  355. void padd(ce) /* AX = BX + AX */
  356. Pcells  ce;
  357. {   I32s  tval;
  358.  
  359.     is.iip = is.dib = 1;
  360.     if (is.eins->exec)
  361.         return ;
  362.     tval = flaw(ce);
  363.     is.dreg  = &(ce->c.re[mo(tval, NUMREG)]);
  364.     tval = 1 + flaw(ce);
  365.     is.sval  = ce->c.re[mo(tval, NUMREG)];
  366.     tval = flaw(ce);
  367.     is.sval2 = ce->c.re[mo(tval, NUMREG)];
  368.     is.dran = SoupSize;
  369. }
  370.  
  371. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  372.  * is.dreg  = destination register, where calculation will be stored
  373.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  374.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  375.  * is.dmod  = value by which to modulus destination register
  376.  * is.dran  = range within which to contain destination register
  377.  */
  378. void psub(ce) /* AX = BX - AX */
  379. Pcells  ce;
  380. {   I32s  tval;
  381.  
  382.     is.iip = is.dib = 1;
  383.     if (is.eins->exec)
  384.         return ;
  385.     tval = flaw(ce);
  386.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  387.     tval = 1 + flaw(ce);
  388.     is.sval  =  ce->c.re[mo(tval, NUMREG)];
  389.     tval = flaw(ce);
  390.     is.sval2 = -ce->c.re[mo(tval, NUMREG)];
  391.     is.dran = SoupSize;
  392. }
  393.  
  394. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  395.  * is.dreg = destination register, where moved value will be placed
  396.  * is.sval = value to be placed in the dest reg
  397.  * is.dmod = value by which to modulus destination register
  398.  * is.dran = range within which to contain destination register
  399.  */
  400. void pzero(ce) /* AX = 0 */
  401. Pcells  ce;
  402. {   I32s  tval;
  403.  
  404.     is.iip = is.dib = 1;
  405.     if (is.eins->exec)
  406.         return ;
  407.     tval = flaw(ce);
  408.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  409.     is.sval = 0;
  410. }
  411.  
  412. /* void not0(ce) *(is.dreg) ^= (1 + flaw(ce));
  413.  * is.dreg = destination register, whose bit will be flipped
  414.  * is.dmod = value by which to modulus destination register
  415.  * is.dran = range within which to contain destination register
  416.  */
  417. void pnot0(ce) /* flip low order bit of AX */
  418. Pcells  ce;
  419. {   I32s  tval;
  420.  
  421.     is.iip = is.dib = 1;
  422.     if (is.eins->exec)
  423.         return ;
  424.     tval = flaw(ce);
  425.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  426.     is.dran = SoupSize;
  427. }
  428.  
  429. /* void shl(ce) *(is.dreg) <<= (Reg) (1 + flaw(ce));
  430.  * is.dreg = destination register, whose bits will be shifted left
  431.  * is.dmod = value by which to modulus destination register
  432.  * is.dran = range within which to contain destination register
  433.  */
  434. void pshl(ce) /* shift left all bits of AX */
  435. Pcells  ce;
  436. {   I32s  tval;
  437.  
  438.     is.iip = is.dib = 1;
  439.     if (is.eins->exec)
  440.         return ;
  441.     tval = flaw(ce);
  442.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  443.     is.dran = SoupSize;
  444. }
  445.  
  446. /* void not(ce) *(is.dreg) = ~(is.sval) + flaw(ce);
  447.  * is.dreg = destination register
  448.  * is.sval = value whose bits will be flipped and put in dest reg
  449.  * is.dmod = value by which to modulus destination register
  450.  * is.dran = range within which to contain destination register
  451.  */
  452. void pnot(ce) /* flip all bits of AX */
  453. Pcells  ce;
  454. {   I32s  tval;
  455.  
  456.     is.iip = is.dib = 1;
  457.     if (is.eins->exec)
  458.         return ;
  459.     tval = flaw(ce);
  460.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  461.     is.dran = SoupSize;
  462. }
  463.  
  464. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  465.  * is.dreg = destination register, where moved value will be placed
  466.  * is.sval = value to be placed in the dest reg
  467.  * is.dmod = value by which to modulus destination register
  468.  * is.dran = range within which to contain destination register
  469.  */
  470. void prand(ce) /* AX = tlrand(); */
  471. Pcells  ce;
  472. {   I32s  tval;
  473.  
  474.     is.iip = is.dib = 1;
  475.     if (is.eins->exec)
  476.         return ;
  477.     tval = flaw(ce);
  478.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  479.     is.sval = tlrand();
  480. }
  481.  
  482. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  483.  * is.sval  = value to test for zero
  484.  * is.sval2 = amount to increment IP if is.sval == 0
  485.  * is.iip   = amount to increment IP if is.sval != 0
  486.  */
  487. void pifz(ce) /* execute next instruction, if AX == 0 */
  488. Pcells  ce;
  489. {   I32s  tval;
  490.  
  491.     is.iip = is.dib = 1;
  492.     if (is.eins->exec)
  493.         return ;
  494.     tval = flaw(ce);
  495.     is.sval = ce->c.re[mo(tval, NUMREG)];
  496.     is.sval2 = 2;
  497. }
  498.  
  499. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  500.  * is.sval  = value to test for zero
  501.  * is.sval2 = amount to increment IP if is.sval == 0
  502.  * is.iip   = amount to increment IP if is.sval != 0
  503.  */
  504. void piffl(ce) /* skip next instruction, if flag == 0 */
  505. Pcells  ce;
  506. {   is.iip = is.dib = 1;
  507.     if (is.eins->exec)
  508.         return ;
  509.     is.sval = ce->c.fl;
  510.     is.sval2 = 1;
  511.     is.iip = 2;
  512.     is.dib = 1;
  513. }
  514.  
  515. /* void adr(ce) find address of a template
  516.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  517.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  518.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  519.  * is.dval  = starting address for forward search
  520.  * is.dval2 = starting address for backward search
  521.  * is.dreg  = destination register where target address will be stored
  522.  * is.dreg2 = destination register where template size will be stored
  523.  * is.dreg3 = destination register where offset of target will be stored
  524.  * is.sval  = return address if template size = 0
  525.  * is.sval2 = template size, 0 = no template
  526.  * is.sval3 = search limit, and return for distance actually searched
  527.  * is.dmod  = modulus value for is.dreg
  528.  * is.dmod2 = modulus value for is.dreg2
  529.  * is.dmod3 = modulus value for is.dreg3
  530.  * is.dran  = range to maintain for is.dreg
  531.  * is.dran2 = range to maintain for is.dreg2
  532.  * is.dran3 = range to maintain for is.dreg3
  533.  */
  534. void ptjmp(ce) /* outward template jump */
  535. Pcells  ce;
  536. {   I32s    a, s = 0, tval;
  537.  
  538.     is.iip = is.dib = 1;
  539.     if (is.eins->exec)
  540.         return ;
  541.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  542.     while(1) /* find size of template, s = size */
  543.     {   
  544. #if PLOIDY == 1
  545.         if(soup[ad(a + s)].inst != Nop0 &&
  546.            soup[ad(a + s)].inst != Nop1)
  547. #else /* PLOIDY > 1 */
  548.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  549.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  550. #endif /* PLOIDY > 1 */
  551.             break;
  552.         s++;
  553.     }
  554.     is.dreg  = &(ce->c.ip); /* destination register for address */
  555.     is.dreg2 = &BitBucket; /* destination register for template size */
  556.     is.dreg3 = &BitBucket; /* dest reg for offset */
  557.     tval = flaw(ce);
  558.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  559.     is.sval  = ad(tval); /* target for IP if s == 0 */
  560.     is.sval2 = s;  /* size of template */
  561.     is.sval3 = Search_limit;
  562.     is.dmod  = SoupSize;
  563.     is.dval  = ad(a + s + 1); /* start address for forward search */
  564.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  565.     is.mode  = 0; /* outward jump */
  566.     is.mode2 = 1;
  567.     is.dib = 1;
  568.     is.iip = 0;
  569. }
  570.  
  571. /* void adr(ce) find address of a template
  572.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  573.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  574.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  575.  * is.dval  = starting address for forward search
  576.  * is.dval2 = starting address for backward search
  577.  * is.dreg  = destination register where target address will be stored
  578.  * is.dreg2 = destination register where template size will be stored
  579.  * is.dreg3 = destination register where offset of target will be stored
  580.  * is.sval  = return address if template size = 0
  581.  * is.sval2 = template size, 0 = no template
  582.  * is.sval3 = search limit, and return for distance actually searched
  583.  * is.dmod  = modulus value for is.dreg
  584.  * is.dmod2 = modulus value for is.dreg2
  585.  * is.dmod3 = modulus value for is.dreg3
  586.  * is.dran  = range to maintain for is.dreg
  587.  * is.dran2 = range to maintain for is.dreg2
  588.  * is.dran3 = range to maintain for is.dreg3
  589.  */
  590. void ptjmpb(ce) /* backward template jump */
  591. Pcells  ce;
  592. {   I32s    a, s = 0, tval;
  593.  
  594.     is.iip = is.dib = 1;
  595.     if (is.eins->exec)
  596.         return ;
  597.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  598.     while(1) /* find size of template, s = size */
  599.     {   
  600. #if PLOIDY == 1
  601.         if(soup[ad(a + s)].inst != Nop0 &&
  602.            soup[ad(a + s)].inst != Nop1)
  603. #else /* PLOIDY > 1 */
  604.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  605.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  606. #endif /* PLOIDY > 1 */
  607.             break;
  608.         s++;
  609.     }
  610.     is.dreg  = &(ce->c.ip); /* destination register for address */
  611.     is.dreg2 = &BitBucket; /* destination register for template size */
  612.     is.dreg3 = &BitBucket; /* dest reg for offset */
  613.     tval = flaw(ce);
  614.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  615.     is.sval  = ad(tval); /* target for IP if s == 0 */
  616.     is.sval2 = s;  /* size of template */
  617.     is.sval3 = Search_limit;
  618.     is.dmod  = SoupSize;
  619.     is.dval  = ad(a + s + 1); /* start address for forward search */
  620.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  621.     is.mode  = 2; /* backward jump */
  622.     is.mode2 = 2;
  623.     is.dib = 1;
  624.     is.iip = 0;
  625. }
  626.  
  627. /* void tcall(ce) adr(ce); push(ce); */
  628. /* void adr(ce) find address of a template
  629.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  630.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  631.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  632.  * is.dval  = starting address for forward search
  633.  * is.dval2 = starting address for backward search
  634.  * is.dreg  = destination register where target address will be stored
  635.  * is.dreg2 = destination register where template size will be stored
  636.  * is.dreg3 = destination register where offset of target will be stored
  637.  * is.sval  = return address if template size = 0
  638.  * is.sval2 = template size, 0 = no template
  639.  * is.sval3 = search limit, and return for distance actually searched
  640.  * is.dmod  = modulus value for is.dreg
  641.  * is.dmod2 = modulus value for is.dreg2
  642.  * is.dmod3 = modulus value for is.dreg3
  643.  * is.dran  = range to maintain for is.dreg
  644.  * is.dran2 = range to maintain for is.dreg2
  645.  * is.dran3 = range to maintain for is.dreg3
  646.  */
  647. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  648.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  649.  * is.sval = value to be pushed onto the stack
  650.  */
  651. void ptcall(ce) /* push ip to stack, outward template jump */
  652. Pcells  ce;
  653. {   I32s    a, s = 0;
  654.  
  655.     is.iip = is.dib = 1;
  656.     if (is.eins->exec)
  657.         return ;
  658.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  659.     while(1) /* find size of template, s = size */
  660.     {
  661. #if PLOIDY == 1
  662.         if(soup[ad(a + s)].inst != Nop0 &&
  663.            soup[ad(a + s)].inst != Nop1)
  664. #else /* PLOIDY > 1 */
  665.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  666.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  667. #endif /* PLOIDY > 1 */
  668.             break;
  669.         s++;
  670.     }
  671.     is.dreg  = &(ce->c.ip); /* destination register for address */
  672.     is.dreg2 = &BitBucket; /* destination register for template size */
  673.     is.dreg3 = &BitBucket; /* destination register for offset */
  674.     is.sval  = ad(ce->c.ip + s + 1); /* address to be pushed onto stack */
  675.     is.sval2 = s;  /* size of template */
  676.     is.sval3 = Search_limit;
  677.     is.dmod  = SoupSize;
  678.     is.dval  = ad(a + s + 1); /* start address for forward search */
  679.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  680.     is.mode  = 0; /* outward jump */
  681.     is.mode2 = 1;
  682.     is.dib = 1;
  683.     is.iip = 0;
  684. }
  685.  
  686. /* void adr(ce) find address of a template
  687.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  688.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  689.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  690.  * is.dval  = starting address for forward search
  691.  * is.dval2 = starting address for backward search
  692.  * is.dreg  = destination register where target address will be stored
  693.  * is.dreg2 = destination register where template size will be stored
  694.  * is.dreg3 = destination register where offset of target will be stored
  695.  * is.sval  = return address if template size = 0
  696.  * is.sval2 = template size, 0 = no template
  697.  * is.sval3 = search limit, and return for distance actually searched
  698.  * is.dmod  = modulus value for is.dreg
  699.  * is.dmod2 = modulus value for is.dreg2
  700.  * is.dmod3 = modulus value for is.dreg3
  701.  * is.dran  = range to maintain for is.dreg
  702.  * is.dran2 = range to maintain for is.dreg2
  703.  * is.dran3 = range to maintain for is.dreg3
  704.  */
  705. /* search outward for template, put address in R0, template size in R1,
  706.    and offset in R0, start search at offset +- R0
  707. */
  708. void padr(ce)
  709. Pcells  ce;
  710. {   I32s    a, s = 0, tval;
  711.  
  712.     is.iip = is.dib = 1;
  713.     if (is.eins->exec)
  714.         return ;
  715.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  716.     while(1) /* find size of template, s = size */
  717.     {
  718. #if PLOIDY == 1
  719.         if(soup[ad(a + s)].inst != Nop0 &&
  720.            soup[ad(a + s)].inst != Nop1)
  721. #else /* PLOIDY > 1 */
  722.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  723.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  724. #endif /* PLOIDY > 1 */
  725.             break;
  726.         s++;
  727.     }
  728.     if (s)
  729.     {   tval = flaw(ce);
  730.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  731.         tval = 1 + flaw(ce);
  732.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  733.         tval = 2 + flaw(ce);
  734.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  735.     }
  736.     else
  737.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  738.     is.sval2 = s;  /* size of template */
  739.     is.dmod  = SoupSize;
  740.     is.dran2 = SoupSize;
  741.     is.dmod3 = SoupSize;
  742.     tval = 1 + flaw(ce);
  743.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  744.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  745.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  746.     is.sval3 = Search_limit - tval;
  747.     is.mode  = 0; /* outward search */
  748.     is.mode2 = 1;
  749.     is.iip = s + 1; is.dib = 1;
  750. }
  751.  
  752. /* void adr(ce) find address of a template
  753.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  754.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  755.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  756.  * is.dval  = starting address for forward search
  757.  * is.dval2 = starting address for backward search
  758.  * is.dreg  = destination register where target address will be stored
  759.  * is.dreg2 = destination register where template size will be stored
  760.  * is.dreg3 = destination register where offset of target will be stored
  761.  * is.sval  = return address if template size = 0
  762.  * is.sval2 = template size, 0 = no template
  763.  * is.sval3 = search limit, and return for distance actually searched
  764.  * is.dmod  = modulus value for is.dreg
  765.  * is.dmod2 = modulus value for is.dreg2
  766.  * is.dmod3 = modulus value for is.dreg3
  767.  * is.dran  = range to maintain for is.dreg
  768.  * is.dran2 = range to maintain for is.dreg2
  769.  * is.dran3 = range to maintain for is.dreg3
  770.  */
  771. /* search backward for template, put address in R0, template size in R1,
  772.    and offset in R0, start search at offset - R0
  773. */
  774. void padrb(ce)
  775. Pcells  ce;
  776. {   I32s    a, s = 0, tval;
  777.  
  778.     is.iip = is.dib = 1;
  779.     if (is.eins->exec)
  780.         return ;
  781.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  782.     while(1) /* find size of template, s = size */
  783.     {
  784. #if PLOIDY == 1
  785.         if(soup[ad(a + s)].inst != Nop0 &&
  786.            soup[ad(a + s)].inst != Nop1)
  787. #else /* PLOIDY > 1 */
  788.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  789.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  790. #endif /* PLOIDY > 1 */
  791.             break;
  792.         s++;
  793.     }
  794.     if (s)
  795.     {   tval = flaw(ce);
  796.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  797.         tval = 1 + flaw(ce);
  798.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  799.         tval = 2 + flaw(ce);
  800.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  801.     }
  802.     else
  803.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  804.     is.sval2 = s;  /* size of template */
  805.     is.dmod  = SoupSize;
  806.     is.dran2 = SoupSize;
  807.     is.dmod3 = SoupSize;
  808.     tval = 1 + flaw(ce);
  809.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  810.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  811.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  812.     is.sval3 = Search_limit - tval;
  813.     is.mode  = 2; /* backward search */
  814.     is.mode2 = 2;
  815.     is.iip = s + 1; is.dib = 1;
  816. }
  817.  
  818. /* void adr(ce) find address of a template
  819.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  820.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  821.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  822.  * is.dval  = starting address for forward search
  823.  * is.dval2 = starting address for backward search
  824.  * is.dreg  = destination register where target address will be stored
  825.  * is.dreg2 = destination register where template size will be stored
  826.  * is.dreg3 = destination register where offset of target will be stored
  827.  * is.sval  = return address if template size = 0
  828.  * is.sval2 = template size, 0 = no template
  829.  * is.sval3 = search limit, and return for distance actually searched
  830.  * is.dmod  = modulus value for is.dreg
  831.  * is.dmod2 = modulus value for is.dreg2
  832.  * is.dmod3 = modulus value for is.dreg3
  833.  * is.dran  = range to maintain for is.dreg
  834.  * is.dran2 = range to maintain for is.dreg2
  835.  * is.dran3 = range to maintain for is.dreg3
  836.  */
  837. /* search forward for template, put address in R0, template size in R1,
  838.    and offset in R0, start search at offset + R0
  839.  */
  840. void padrf(ce)
  841. Pcells  ce;
  842. {   I32s    a, s = 0, tval;
  843.  
  844.     is.iip = is.dib = 1;
  845.     if (is.eins->exec)
  846.         return ;
  847.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  848.     while(1) /* find size of template, s = size */
  849.     {
  850. #if PLOIDY == 1
  851.         if(soup[ad(a + s)].inst != Nop0 &&
  852.            soup[ad(a + s)].inst != Nop1)
  853. #else /* PLOIDY > 1 */
  854.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  855.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  856. #endif /* PLOIDY > 1 */
  857.             break;
  858.         s++;
  859.     }
  860.     if (s)
  861.     {   tval = flaw(ce);
  862.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  863.         tval = 1 + flaw(ce);
  864.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  865.         tval = 2 + flaw(ce);
  866.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  867.     }
  868.     else
  869.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  870.     is.sval2 = s;  /* size of template */
  871.     is.dmod  = SoupSize;
  872.     is.dran2 = SoupSize;
  873.     is.dmod3 = SoupSize;
  874.     tval = 1 + flaw(ce);
  875.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  876.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  877.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  878.     is.sval3 = Search_limit - tval;
  879.     is.mode  = 1; /* forward search */
  880.     is.mode2 = 1;
  881.     is.iip = s + 1; is.dib = 1;
  882. }
  883.  
  884. /* void malchm(ce) is.sval2 = mal(ce,&is.sval3,is.sval,is.mode2);
  885.  *                 *(is.dreg) = is.sval3;
  886.  *                 chmode(ce,is.sval3,is.sval2,is.mode);
  887.  * is.dreg  = destination register where allocated address is stored
  888.  * is.sval  = requested size of block for mal()
  889.  * is.sval2 = flawed size of block (assigned in instruct.c)
  890.  * is.sval3 = suggested address, and allocated address
  891.  * is.mode  = memory protection mode (rwx), probably MemModeProt
  892.  * is.mode2 = memory allocation mode for mal()
  893.  */
  894. void pmal(ce)  /* allocate space for a new cell */
  895. Pcells  ce;
  896. {   I32s  tval;
  897.  
  898.     is.iip = is.dib = 1;
  899.     if (is.eins->exec)
  900.         return ;
  901.     tval = flaw(ce);
  902.     is.dreg  = &(ce->c.re[mo(tval, NUMREG)]);
  903.     tval = 1 + flaw(ce);
  904.     is.sval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  905.     tval = flaw(ce);
  906.     is.sval3 = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  907.     if (is.sval3 < 0)
  908.         is.mode2 = 1; /* better fit */
  909.     else
  910.         is.mode2 = 6; /* suggester address (is.sval3) */
  911.     is.mode = MemModeProt; /* only write privelage works at the moment */
  912. }
  913.  
  914. /* void divide(ce) cell division
  915.  * is.mode  = divide mode (3 steps)
  916.  * is.sval  = offset of IP into daughter's genome
  917.  * is.sval2 = eject genome from soup = 0, !0 = leave in soup
  918.  */
  919. void pdivide(ce)  /* give life to new cell by puting in queue */
  920. Pcells  ce;
  921. {   I32s  tval;
  922.  
  923.     is.iip = is.dib = 1;
  924.     if (is.eins->exec)
  925.         return ;
  926.     is.mode  = 2;  /* full division */
  927.     tval = flaw(ce);
  928.     is.sval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  929.     tval = 1 + flaw(ce);
  930.     is.sval2 = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  931. }
  932.  
  933. #endif  /* INST == 3 */
  934.